/*
 * XDVVector.h
 *
 *  Created on: Jun 2, 2013
 *      Author: daviD, MakotoMatayoshi
 */

#ifndef XDVVECTOR_H_
#define XDVVECTOR_H_

#include "XDVFloatUtility.h"
class XDVVector3
{
public:
	XDVVector3(float x, float y, float z);
	virtual ~XDVVector3();
	/*
	 * The first component of the vector.
	 */
	float x;

	/*
	 *  The second component of the vector.
	 */
	float y;

	/*
	 *  The third component of the vector.
	 */
	float z;

	/*
	 *  Component wise addition.
	 */
	XDVVector3& operator+=( const XDVVector3& o );

	/*
	 *  Component wise subtraction.
	 */
	XDVVector3& operator-=( const XDVVector3& o );

	/*
	 *  Component wise scalar subtract
	 */
	XDVVector3& operator-=( float s );

	/*
	 *  Component wise scalar addition
	 */
	XDVVector3& operator+=( float s );

	/*
	 *  Component wise scalar multiplication.
	 */
	XDVVector3& operator*=( float s );

	/*
	 * Component wise scalar division.
	 */
    XDVVector3& operator/=( float s );

	/*
	 *  Component wise multiplication.
	 */
	XDVVector3& operator*=( const XDVVector3& o );

	/*
	 *  Component wise division.
	 */
	XDVVector3& operator/=( const XDVVector3& o );

	/*
	 *  Returns component at specified index.
	 */
	float& operator[]( size_t i ){ return (&x)[i];}

	/*
	 *  Returns pointer to the first float.
	 */
	float* begin(){return &x;}

	/*
	 *  Returns pointer to one beyond the last float.
	 */
	float* end(){return &x+3;}

	/*
	 *  Normalizes this vector.
	 */
	//void normalize();

	/*
	 * Component wise multiplication.
	 */
	XDVVector3 operator*( const XDVVector3& o ) const;

	/*
	 *  Component wise division.
	 */
	XDVVector3 operator/( const XDVVector3& o ) const;

	/*
	 *  Component wise addition.
	 */
	XDVVector3 operator+( const XDVVector3& o ) const;

	/*
	 * Component wise subtraction.
	 */
	XDVVector3 operator-( const XDVVector3& o ) const;

	/*
	 *  Component wise subtraction.
	 */
	XDVVector3 operator-() const;

	/*
	 * Component wise scalar multiplication.
	 */
	XDVVector3 operator*( float s ) const;

	/*
	 * Component wise scalar division.
	 */
	XDVVector3 operator/( float s ) const;

	/*
	 *  Returns component at specified index.
	 */
	const float& operator[]( size_t i ) const { return (&x)[i];}

	/*
	 * Returns true if vectors are bitwise equal.
	 */
	bool operator==( const XDVVector3& o ) const;

	/*
	 * Returns true if vectors are bitwise inequal.
	 */
	bool operator!=( const XDVVector3& o ) const;

	/*
	 *  Returns const pointer to the first float.
	 */
	const float* begin() const {return &x;}

	/*
	 * Returns const pointer to one beyond the last float.
	 */
	const float* end() const {return &x+3;}

	/*
	* Returns cross product of two vectors.
	*/
	XDVVector3 Cross( const XDVVector3& a, const XDVVector3& b );


	/*
	* Returns length of the vector.
	*/
	float Length( const XDVVector3& v );

	/*
	* Returns dot product (inner product) of two vectors.
 	*/
	float Dot( const XDVVector3& a, const XDVVector3& b );

	/*
	 * Returns the vector normalized.
	 * */
	 //XDVVector3 Normalize( const XDVVector3& v );

	 /*
	 * Returns component wise maximum of two vectors.
	 */
	 //XDVVector3    max( const XDVVector3& a, const XDVVector3& b );

	 /*
	 * Returns component wise minimum of two vectors.
	 */
	 //XDVVector3    min( const XDVVector3& a, const XDVVector3& b );

	 /*
	 * Returns component wise absolute of the vector.
	 */
	 XDVVector3 Abs( const XDVVector3& v );

	 /*
	 * Returns linear blend between two values. Formula is x*(1-a)+y*a.
     */
	 //XDVVector3    mix( const XDVVector3& x, const XDVVector3& y, float a );

	 /*
	 * Returns distance between two values.
	 */
	 float Distance( const XDVVector3& p0, const XDVVector3& p1 );

	 /*
	  * Returns value with components clamped between [min,max].
	  */
	//XDVVector3    clamp( const XDVVector3& v, const XDVVector3& min, const XDVVector3& max );

	  /*
	  * Returns value with components clamped between [0,1].
	  */
	  //XDVVector3    saturate( const XDVVector3& v );

	  /*
	  * Returns true if all components are valid numbers.
	  */
	  //bool    check( const XDVVector3& v );

	  /*
	  * Returns negated vector. This function is useful for scripting where overloaded operators are not available.
	  */
	  XDVVector3 Neg( const XDVVector3& a );

	 /*
	  * Adds two vectors together. This function is useful for scripting where overloaded operators are not available.
      */
	  XDVVector3 Add( const XDVVector3& a, const XDVVector3& b );

	  /*
	  * Subtracts two vectors together. This function is useful for scripting where overloaded operators are not available.
      */
	  XDVVector3 Sub( const XDVVector3& a, const XDVVector3& b );

	  /*
	  * Multiplies vector by scalar. This function is useful for scripting where overloaded operators are not available.
	  */
	  XDVVector3 Mul( const XDVVector3& a, float b );

	  /*
	  * Multiplies vector by scalar. This function is useful for scripting where overloaded operators are not available.
 	  */
	  XDVVector3 Mul( float b, const XDVVector3& a );
};

#endif /* XDVVECTOR_H_ */
